home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MACSHELL
/
MS1
/
COMMANDS
/
DIFF.C
< prev
next >
Wrap
Text File
|
1992-12-02
|
9KB
|
368 lines
/*
* MacShell Source File
*
* Copyright (c) 1989, 1990, 1991, 1992 Suick Bay Technologies. All rights reserved.
*
*
* RESTRICTIONS ON MacShell program and source code.
*
* Ñ╩MacShell¬ is a product of Suick Bay Technologies and is provided for
* restricted use by the owner of the CDROM "Disk to the future II".
*
* Ñ╩No permission is granted for any commercial use without the written
* consent of the Suick Bay Technologies.
*
* Ñ╩No permission is granted for any redistribution of any kind use without
* the written consent of the Suick Bay Technologies.
*
* Ñ╩Permission is granted to use this for any personal noncommercial use.
*
* Ñ╩You may not distribute source or executable code at all, nor may you
* distribute it with or within a commercial product without the written
* consent of the Suick Bay Technologies. Please send modifications to
* the author for inclusion in updates to the program. Thanks.
*
*
* MacShell¬ IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* SUICK BAY TECHNOLOGIES SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY MACSHELL
* OR ANY PART THEREOF.
*
* In no event will Suick Bay Technologies be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Suick Bay Technologies has been advised of the possibility of such damages.
*
* Suick Bay Technologies can be reached at:
*
* 8768 Cottonwood lane
* Maple Grove, MN 55369
* Voice: (612) 425-7025
* AppleLink: D5233
*
*
* No parts of this software may be reproduced or stored in a
* retrieval system or transmitted in any form, or any means,
* electronic, mechanical, photocopying, recording or otherwise,
* without the prior written permission of Suick Bay Technologies.
*
* Spread the word and not the disk.
*
* SPK 012290 : Initial
*/
#include "SystemPub.h"
#include "Proc.h"
#include "ShellPub.h"
#include "path.h"
#define BUFSIZE 256L
#define _DIFFDEBUG
/*******************************************************************
*
* Function DIFF
*
*
* diff [options] file1 file2
*
* options
* -h do a fast half-hearted job.
* -b trailing blanks are ignored.
*
*******************************************************************/
#define diffFast (**MyShell).Proc[ProcID].bflags.f0
#define diffBlank (**MyShell).Proc[ProcID].bflags.f1
#define diffAbort (**MyShell).Proc[ProcID].bflags.f2
#define misLineCnt (**MyShell).Proc[ProcID].int0
int16 StrDiff( char *s1, char *s2, Boolean fast )
{
if( fast )
return( strcmp( s1, s2 ) );
#ifdef DIFFDEBUG
printf( "StrDiff \n:%s:%s", s1, s2 );
#endif
while( *s1 )
{
/* remove white space from line */
while( *s1 && isShellSpace( *s1 ) )
s1++;
while( *s2 && isShellSpace( *s2 ) )
s2++;
while( *s1 && (*s1 == *s2 ) && !isShellSpace( *s1 ) )
{
s1++;
s2++;
}
if( *s1 )
{
if( isShellSpace( *s1 ) && isShellSpace( *s2 ) )
;
else /* error */
return( 1 );
}
else if( *s2 ) /* error */
return( 1 );
else
return( 0 ); /* ok */
}
}
/*******************************************************************/
Boolean SyncToLine( char *line, int16 fileRefNum, int16 syncCnt,
int32 *syncPos, Boolean fast )
{
char buf[ BUFSIZE ];
OSErr err;
#ifdef DIFFDEBUG
printf( "SyncToLine ref %d %s", fileRefNum, line );
#endif
while( syncCnt-- )
{
err = GetFPos( fileRefNum, syncPos );
err = ReadLine( fileRefNum, buf, BUFSIZE );
if( err )
break;
if( StrDiff( line, buf, fast ) == 0 ) /* in sync */
return( TRUE );
}
return( FALSE );
}
/*******************************************************************/
void ListDiffTo( WHandle ShellWh, int16 ProcID, char indicator,
int16 fileRefNum, int32 syncPos, int16 *lineNum )
{
int32 fPos;
char buf[ BUFSIZE ];
OSErr err;
err = GetFPos( fileRefNum, &fPos );
#ifdef DIFFDEBUG
printf( "ListDiffTo ref %d from %ld to %ld\n", fileRefNum, fPos, syncPos );
#endif
while( fPos < syncPos )
{
err = ReadLine( fileRefNum, buf, BUFSIZE );
procPrintf( ShellWh, ProcID, "%2d %c %s", *lineNum, indicator, buf );
if( err )
break;
err = GetFPos( fileRefNum, &fPos );
(*lineNum)++;
}
}
/*******************************************************************/
void DIFFFile( WHandle ShellWh, int16 ProcID, char *file1, char *file2 )
{
int16 aRefNum, bRefNum,
aErr, bErr,
aLineNum, bLineNum,
filesSame = TRUE,
cantDiff = TRUE;
char aBuf[ BUFSIZE ],
bBuf[ BUFSIZE ];
int32 aPos, bPos, syncPos;
ShellWindRec **MyShell = (ShellWindRec **) (**ShellWh).thing;
aRefNum = OpenFileDirect( file1, 'TEXT', fsRdPerm );
if( aRefNum )
{
bRefNum = OpenFileDirect( file2, 'TEXT', fsRdPerm );
if( bRefNum )
{
aLineNum = 1;
bLineNum = 1;
cantDiff = FALSE;
while( filesSame && !diffAbort )
{
if( UserAbort() )
diffAbort = TRUE;
aErr = GetFPos( aRefNum, &aPos );
bErr = GetFPos( bRefNum, &bPos );
aErr = ReadLine( aRefNum, aBuf, BUFSIZE );
bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
if( aErr || bErr )
break;
else /* compare differences */
{
if( StrDiff( aBuf, bBuf, diffFast ) ) /* lines are different */
{
if( SyncToLine( aBuf, bRefNum, misLineCnt, &syncPos, diffFast ) )
{
SetFPos( bRefNum, fsFromStart, bPos );
procPrintf( ShellWh, ProcID, "add at line %d\n", aLineNum );
ListDiffTo( ShellWh, ProcID, '>', bRefNum, syncPos, &bLineNum );
bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
}
else
{
SetFPos( bRefNum, fsFromStart, bPos );
if( SyncToLine( bBuf, aRefNum, misLineCnt, &syncPos, diffFast ) )
{
SetFPos( aRefNum, fsFromStart, aPos );
procPrintf( ShellWh, ProcID, "add at line %d\n", bLineNum );
ListDiffTo( ShellWh, ProcID, '<', aRefNum, syncPos, &aLineNum );
}
else
{
procPrintf( ShellWh, ProcID, "change\n" );
SetFPos( aRefNum, fsFromStart, aPos );
SetFPos( bRefNum, fsFromStart, bPos );
aErr = ReadLine( aRefNum, aBuf, BUFSIZE );
bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
procPrintf( ShellWh, ProcID, "%2d > %s%2d < %s",
aLineNum, aBuf, bLineNum, bBuf );
}
}
}
}
aLineNum++;
bLineNum++;
}
FSClose( aRefNum );
FSClose( bRefNum );
}
else
{
FSClose( aRefNum );
procPrintf( ShellWh, ProcID, "diff : can't open %s\n", file2 );
}
}
else
procPrintf( ShellWh, ProcID, "diff : can't open %s\n", file1 );
if( cantDiff )
procPrintf( ShellWh, ProcID, "diff : can't compare %s and %s\n",
file1, file2 );
ResetShellPWD( ShellWh );
}
/*******************************************************************/
Boolean DoDIFF( int16 ProcToken, WHandle ShellWh, int16 ProcID, char *string )
{
int16 i, argc;
char *cp, arg1[ 256 ], arg2[ 256 ];
ShellWindRec **MyShell = (ShellWindRec **) (**ShellWh).thing;
switch( ProcToken )
{
case PROC_INIT :
(**MyShell).Proc[ ProcID ].flags = TRUE;
break;
case PROC_TERM :
case PROC_BREAK :
diffAbort = TRUE;
/* Tell the shell that we're done */
SendOutToken( ShellWh, ProcID, PROC_BREAK );
/* Turn ourself off */
(**MyShell).Proc[ ProcID ].ProcActive = FALSE;
break;
case PROC_STDIN :
if( (**MyShell).Proc[ ProcID ].flags )
{
(**MyShell).Proc[ ProcID ].flags = FALSE;
diffFast = FALSE;
diffBlank = FALSE;
diffAbort = FALSE;
misLineCnt = 16;
/* get arguments */
argc = (**MyShell).Proc[ ProcID ].argc;
for( i = 1; i < argc; i++ )
{
GetArgv( ShellWh, ProcID, i, arg1 );
cp = arg1;
if( *cp++ == '-' )
while( *cp )
switch( *cp++ )
{
case 'h' : /* fast half-hearted job */
diffFast = TRUE;
misLineCnt = 4;
break;
case 'b' : /* trailing blanks are ignored */
diffBlank = TRUE;
break;
case 's' : /* resync count */
break;
}
}
*arg1 = '\0';
*arg2 = '\0';
for( i = 1; i < (**MyShell).Proc[ ProcID ].argc; i++ )
{
if( *arg1 == '\0' )
{
GetArgv( ShellWh, ProcID, i, arg1 );
if( *arg1 == '-' )
*arg1 = '\0';
}
else if( *arg2 == '\0' )
{
GetArgv( ShellWh, ProcID, i, arg2 );
if( *arg2== '-' )
*arg2 = '\0';
else
break;
}
}
if( *arg1 && *arg2 )
DIFFFile( ShellWh, ProcID, arg1, arg2 );
/* Tell the shell that we're done */
SendOutToken( ShellWh, ProcID, PROC_BREAK );
/* Turn ourself off */
(**MyShell).Proc[ ProcID ].ProcActive = FALSE;
return( FALSE );
}
}
}